package com.dhcc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dhcc.base.BaseServiceImpl;
import com.dhcc.entity.SysResource;
import com.dhcc.httpApiService.IdGeneratorService;
import com.dhcc.mapper.SysResourceMapper;
import com.dhcc.service.SysResourceService;
import com.dhcc.service.SysUserService;
import com.dhcc.utils.ResourceTreeBuilder;
import com.dhcc.response.SysResourceListTree;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 资源表接口实现类
 * @ProjectName Dhcc-Cloud
 * @PackageName com.dhcc.service.impl
 * @Title SysResourceServiceImpl
 * @Date 2024/12/5 下午10:19
 * @Author LiuGuoting
 */
@Service
public class SysResourceServiceImpl extends BaseServiceImpl<SysResourceMapper, SysResource> implements SysResourceService {
    /**
     * ID 生成器服务
     */
    @Resource
    private IdGeneratorService idGeneratorService;
    /**
     * 用户服务接口
     */
    @Resource
    private SysUserService sysUserService;

    /**
     * 自定义分页查询资源列表树
     *
     * @param page        分页对象
     * @param sysResource 资源对象，用于查询条件
     * @return IPage<SysResourceVO>
     */
    @Override
    public IPage<SysResourceListTree> selectResourcePage(IPage<SysResource> page, SysResource sysResource) {
        // 1. 查询父资源（分页）
        QueryWrapper<SysResource> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .like(StringUtils.hasText(sysResource.getResourceName()), SysResource::getResourceName, sysResource.getResourceName())
                // 仅查询父资源
                .isNull(SysResource::getResourceParentId)
                // 过滤未删除的资源
                .eq(SysResource::getDelFlag, 0)
                // 按排序字段升序
                .orderByDesc(SysResource::getSort);

        // 分页查询父资源
        IPage<SysResource> parentPage = baseMapper.selectPage(page, wrapper);
        List<SysResource> parentResources = parentPage.getRecords();
        for (SysResource resource : parentResources) {
            // 补充创建人和修改人的用户名
            resource.setCreateUser(sysUserService.getUserNameById(resource.getCreateUser()));
            resource.setUpdateUser(sysUserService.getUserNameById(resource.getUpdateUser()));
        }

        // 2. 查询所有资源（非分页，用于构建完整资源树）
        List<SysResource> allResources = baseMapper.selectList(new QueryWrapper<SysResource>()
                .lambda()
                // 过滤未删除的资源
                .eq(SysResource::getDelFlag, 0)
                // 按排序字段升序
                .orderByDesc(SysResource::getSort));
        for (SysResource resource : allResources) {
            // 补充创建人和修改人的用户名
            resource.setCreateUser(sysUserService.getUserNameById(resource.getCreateUser()));
            resource.setUpdateUser(sysUserService.getUserNameById(resource.getUpdateUser()));
        }

        // 3. 构建资源树，将每个父资源附加子资源
        List<SysResourceListTree> resourceTree = parentResources.stream()
                .map(parentResource -> {
                    // 将父资源转换为 VO
                    SysResourceListTree parentResourceVO = ResourceTreeBuilder.convertToVO(parentResource);
                    // 构建当前父资源的子资源树
                    List<SysResourceListTree> children = ResourceTreeBuilder.buildResourceTree(
                            allResources,
                            parentResource.getId());
                    // 设置子资源
                    parentResourceVO.setChildren(children);
                    return parentResourceVO;
                })
                .collect(Collectors.toList());

        // 4. 构建分页对象
        IPage<SysResourceListTree> resourceVOPage = new Page<>(parentPage.getCurrent(), parentPage.getSize(), parentPage.getTotal());
        // 设置树形结构的资源列表
        resourceVOPage.setRecords(resourceTree);

        return resourceVOPage;
    }

    /**
     * 查询资源树
     *
     * @return List<SysResourceVO>
     */
    @Override
    public List<SysResourceListTree> listResourceTree() {
        LambdaQueryWrapper<SysResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysResource::getDelFlag, 0).orderByDesc(SysResource::getSort);
        List<SysResource> allResources = baseMapper.selectList(wrapper);
        // 重新设置创建用户的名称和修改用户的名称
        for (SysResource sysResource : allResources) {
            sysResource.setCreateUser(sysUserService.getUserNameById(sysResource.getCreateUser()));
            sysResource.setUpdateUser(sysUserService.getUserNameById(sysResource.getUpdateUser()));
        }
        return ResourceTreeBuilder.buildResourceTree(allResources, null);
    }

    /**
     * 新增资源
     *
     * @param sysResource 资源信息实体对象
     * @return Boolean
     */
    @Override
    public Boolean addResource(SysResource sysResource) {
        validateResourceParams(sysResource);
        // 如果为顶级资源，则查询是否有同名的顶级资源
        LambdaQueryWrapper<SysResource> wrapperA = new LambdaQueryWrapper<>();
        wrapperA.eq(SysResource::getResourceName, sysResource.getResourceName());
        wrapperA.isNull(SysResource::getResourceParentId);
        wrapperA.eq(SysResource::getDelFlag, 0);
        if (count(wrapperA) > 0) {
            throw new IllegalArgumentException("同名根资源已存在！");
        }
        // 查询该顶级资源下是否有同名资源
        LambdaQueryWrapper<SysResource> wrapperB = new LambdaQueryWrapper<>();
        wrapperB.eq(SysResource::getResourceName, sysResource.getResourceName());
        wrapperB.eq(SysResource::getResourceParentId, sysResource.getResourceParentId());
        if (count(wrapperB) > 0) {
            throw new IllegalArgumentException("该资源下已存在同名资源！");
        }
        sysResource.setId(idGeneratorService.nextId().toString());
        return baseMapper.insert(sysResource) > 0;
    }

    /**
     * 更新资源
     *
     * @param sysResource 资源信息实体对象
     * @return Boolean
     */
    @Override
    public Boolean updateResource(SysResource sysResource) {
        validateResourceParams(sysResource);
        return baseMapper.updateById(sysResource) > 0;
    }

    /**
     * 查询资源详情（基本信息）
     *
     * @param id 资源 ID
     * @return SysResource
     */
    @Override
    public SysResource getResourceById(String id) {
        return baseMapper.selectById(id);
    }

    /**
     * 启用/禁用资源
     *
     * @param id     资源 ID
     * @param status 资源状态（0：启用，1：禁用）
     * @return Boolean
     */
    @Override
    public Boolean changeResourceStatus(String id, int status) {
        LambdaUpdateWrapper<SysResource> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SysResource::getId, id).set(SysResource::getStatus, status);
        return baseMapper.update(null, wrapper) > 0;
    }

    /**
     * 批量启用/禁用资源
     *
     * @param ids    资源 ID 列表
     * @param status 资源状态（0：启用，1：禁用）
     * @return Boolean
     */
    @Override
    public Boolean changeResourceStatuses(List<String> ids, int status) {
        if (ids == null || ids.isEmpty() || (status != 0 && status != 1)) {
            throw new IllegalArgumentException("参数错误");
        }
        LambdaUpdateWrapper<SysResource> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(SysResource::getId, ids).set(SysResource::getStatus, status);
        return baseMapper.update(null, wrapper) > 0;
    }

    /**
     * 校验资源参数
     *
     * @param sysResource 资源信息实体对象
     */
    private void validateResourceParams(SysResource sysResource) {
        if (!StringUtils.hasText(sysResource.getResourceName())) {
            throw new IllegalArgumentException("资源名称不能为空");
        }
        if (sysResource.getResourceParentId() != null) {
            SysResource parentResource = baseMapper.selectById(sysResource.getResourceParentId());
            if (parentResource == null || parentResource.getDelFlag() == 1) {
                throw new IllegalArgumentException("父资源无效或已删除");
            }
        }
    }
}
